package cn.darkhorse.common.util;

import cn.darkhorse.common.annotation.ReportForm;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class ExcelTotalUtil {
    public static <T> Map<String,Object>  getTotal(List<T> list) {
        Map<String,Object> map=new HashMap<>();
        Map<String,Integer> typeMap=new HashMap<>();
        if(null!=list&&list.size()>0){
            list.forEach(item->{
                if (null!=item) {
                    Field[] declaredFields = item.getClass().getDeclaredFields();
                    for (int i = 0; i < declaredFields.length; i++) {
                        Field field = declaredFields[i];
                        ReportForm attrs = field.getAnnotation(ReportForm.class);
                        if (null != attrs && null != attrs.dataType()) {
                            field.setAccessible(true);
                            Object val = null;
                            try {
                                val = field.get(item);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }
                            if (null != val) {
                                Class<?> type = field.getType();
                                if(type.equals(String.class)){
                                    if(val.equals("--")){
                                        val= BigDecimal.ZERO;
                                    }else{
                                        val=new BigDecimal(val.toString());
                                    }
                                }
                                if (attrs.dataType().equals(ReportForm.DateType.BIGDECIMAL)) {
                                    if (map.containsKey(field.getName())) {
                                        BigDecimal old = (BigDecimal) map.get(field.getName());
                                        map.put(field.getName(), old.add((BigDecimal) val));
                                        if(!typeMap.containsKey(field.getName())) {
                                            typeMap.put(field.getName(), attrs.dataType().value());
                                        }
                                    } else {
                                        map.put(field.getName(), val);
                                    }
                                }
                                if (attrs.dataType().equals(ReportForm.DateType.INTEGER)) {
                                    if (map.containsKey(field.getName())) {
                                        Integer old = (Integer) map.get(field.getName());
                                        map.put(field.getName(), old + (Integer) val);
                                        if(!typeMap.containsKey(field.getName())) {
                                            typeMap.put(field.getName(), attrs.dataType().value());
                                        }
                                    } else {
                                        map.put(field.getName(), val);
                                    }
                                }
                            }else {
                                if (attrs.dataType().equals(ReportForm.DateType.BIGDECIMAL)) {
                                    map.put(field.getName(), BigDecimal.ZERO);
                                }
                                if (attrs.dataType().equals(ReportForm.DateType.INTEGER)) {
                                    map.put(field.getName(), 0);
                                }
                            }
                        }
                    }
                }
            });
        }
        checkMapValue(map,typeMap);
        return map;
    }

    /**
     * 金额保留三位小数
     * @param map
     * @param typeMap
     */
    public static void checkMapValue(Map<String, Object> map, Map<String, Integer> typeMap){
        Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, Object> entry = entries.next();
            String key = entry.getKey();
            if(typeMap.containsKey(key)){
                int type=typeMap.get(key);
                if(ReportForm.DateType.BIGDECIMAL.value()==type){
                    BigDecimal value=(BigDecimal) entry.getValue();
                    map.put(key,value.setScale(3, RoundingMode.HALF_UP));
                }
            }
        }
    }
}
